﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Starfire3d.Interfaces;
using Starfire3d.Data.Objects;

namespace Starfire3d.TokenReader
{
    public class TokenReader
    {
        #region Defines
        const string DATA_EXT = ".txt";
        #endregion

        #region Attributes
        private string filePath;
        private string filename;
        private List<string> fileStrings = new List<string>();
        private List<MetaObject> metaObjectList = new List<MetaObject>();
        #endregion

        #region Constructor
        public TokenReader(string filepath, string filename)
        {
            this.filePath = filepath;
            this.filename = filename;
        }
        #endregion

        #region Properties
        public string FileName
        {
            get { return filename; }
        }

        public string FilePath
        {
            get { return filePath; }
            set { filePath = value; }
        }

        public List<MetaObject> GetMetaObjectList
        {
            get { return metaObjectList; }
        }
        #endregion

        public static void LoadGameDataFiles(string basePath)
        {
            // Pre-load each file from the base directory
            string[] filesToLoad = Directory.GetFiles(basePath);

            foreach (string fileName in filesToLoad)
            {
                int start = fileName.LastIndexOf('\\');
                int end = fileName.IndexOf(".");

                string file = fileName.Substring(start + 1, end - start - 1);

                TokenReader reader = new TokenReader(basePath, file);
                reader.Load();

                IDataItem obj = null;
                foreach (MetaObject meta in reader.GetMetaObjectList)
                {
                    obj = DataFactory.BuildDataItem(meta.Name);
                    try
                    {
                        obj.BuildFromMetaData(meta);
                        DataItemStore.Add(meta.Name, obj);
                    }
                    catch(Exception e)
                    {
                    }
                }
            }
        }

        #region Public Methods
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool Load()
        {
            BuildMetaObjectList();

            if (!ValidateHeader())
                return false;

            MetaObject newMeta = null;
            string objectName = "";

            foreach (string line in fileStrings)
            {
                if (line == filename) continue;

                // Check for a new metaObject
                string[] tokens = line.Split(':');
                if (tokens[0] == "OBJECT")
                {
                    objectName = tokens[1];
                    continue;
                }

                if (tokens.Count() == 1 && tokens[0] == objectName)
                {
                    if (newMeta != null)
                        metaObjectList.Add(newMeta);

                    newMeta = new MetaObject();
                    newMeta.Name = tokens[0];
                    continue;
                }

                //
                newMeta.AddToken(line);
            }

            if (newMeta != null)
                metaObjectList.Add(newMeta);
            
            return true;
        }
        #endregion

        #region Private methods
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool ValidateHeader()
        {
            if (fileStrings.Count == 0)
                return false;
            if (fileStrings[0] != filename)
                return false;

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void BuildMetaObjectList()
        {
            string fullPath = filePath + filename + DATA_EXT;
            if (!File.Exists(fullPath))
                return;
            
            char[] charsToTrim = { ' ', '[', ']' };

            using (StreamReader sr = File.OpenText(fullPath))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                {
                    s = s.Trim();
                    if (s == string.Empty || !(s.StartsWith("[") && s.EndsWith("]"))) continue;

                    fileStrings.Add(s.Trim(charsToTrim));
                }
            }
        }
        #endregion
    }
}
